package cn.tom.config;

import cn.tom.tool.JwtUtil;
import cn.tom.tool.XResp;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

//  可以继承这个 OncePerRequestFilter
//  可以继承这个 BasicAuthenticationFilter， 无需指定过滤器的顺序
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
    public JwtAuthorizationFilter(AuthenticationManager authenticationManager) {
        //指定密码比对器
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        System.out.println("获取请求头部的 JWT  Token");
        String token = request.getHeader("Authorization");
        System.out.println("头部的 Authorization=" + token);
        // 如果请求头中没有Authorization信息则直接放行了
        if (token == null || token.startsWith("Bearer ") == false  ) {
            System.out.println("如果请求头中没有Authorization信息则直接放行了");
            filterChain.doFilter(request, response);
            return;
        }
        System.out.println("请求头中有token，则进行解析，并且设置授权信息");
        token = token.substring(7);
        System.out.println("JWT token=" + token);
        if (JwtUtil.isValid(token) == false) {
            System.out.println("Token 校验失败有人篡改过， 或者有效期已过");
            try {
                response.setStatus(403);   // 权限不够
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json");
                response.getWriter().println(XResp.packJson(403, "权限不够", ""));
                response.flushBuffer();
            } catch (Exception e) {
                System.err.println("response 写失败");
            }
            return;
        }
        System.out.println("Token 校验成功， 通过JWT Token 获取 登录账号及权限表，别查数据库啊");
        String username = JwtUtil.getUsername(token);
        System.out.println("Token 校验成功 username=" + username);
        List<String> roles = JwtUtil.getRoles(token);
        System.out.println("Token 校验成功 roles=" + roles);
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for(String s: roles) {
            authorities.add(new SimpleGrantedAuthority(s));
        }
        User  user = new User(username, "", authorities);
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(user,null, user.getAuthorities());
        //authenticationToken.setAuthenticated(true);
        System.out.println("放置登录信息=" + authenticationToken);
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        System.out.println("让SpringSecurity 的过滤器去处理权限管理事宜");
        filterChain.doFilter(request, response);
    }
}
